IDEMPIERE-2771 Improve 2pack tracing for errors / implement mail notifier for 2packs
This commit is contained in:
parent
6d4e756e12
commit
4029fbd81c
|
@ -0,0 +1,11 @@
|
|||
SET SQLBLANKLINES ON
|
||||
SET DEFINE OFF
|
||||
|
||||
-- IDEMPIERE-2771 Improve 2pack tracing for errors
|
||||
-- Aug 19, 2015 9:55:02 PM COT
|
||||
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200067,0,0,TO_DATE('2015-08-19 21:55:02','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2015-08-19 21:55:02','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','EMAIL_NOTIFY_2PACK',' ','EMail to get 2Pack Notifications','D','C','12ab33a5-4129-4d5b-9066-dbdbc20df816')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201508192155_IDEMPIERE-2771.sql') FROM dual
|
||||
;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
-- IDEMPIERE-2771 Improve 2pack tracing for errors
|
||||
-- Aug 19, 2015 9:55:02 PM COT
|
||||
INSERT INTO AD_SysConfig (AD_SysConfig_ID,AD_Client_ID,AD_Org_ID,Created,Updated,CreatedBy,UpdatedBy,IsActive,Name,Value,Description,EntityType,ConfigurationLevel,AD_SysConfig_UU) VALUES (200067,0,0,TO_TIMESTAMP('2015-08-19 21:55:02','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2015-08-19 21:55:02','YYYY-MM-DD HH24:MI:SS'),100,100,'Y','EMAIL_NOTIFY_2PACK',' ','EMail to get 2Pack Notifications','D','C','12ab33a5-4129-4d5b-9066-dbdbc20df816')
|
||||
;
|
||||
|
||||
SELECT register_migration_script('201508192155_IDEMPIERE-2771.sql') FROM dual
|
||||
;
|
||||
|
|
@ -42,7 +42,7 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2870394087507976203L;
|
||||
private static final long serialVersionUID = 2300170888492939423L;
|
||||
|
||||
public static final String ADDRESS_VALIDATION = "ADDRESS_VALIDATION";
|
||||
public static final String ALERT_SEND_ATTACHMENT_AS_XLS = "ALERT_SEND_ATTACHMENT_AS_XLS";
|
||||
|
@ -79,6 +79,7 @@ public class MSysConfig extends X_AD_SysConfig
|
|||
public static final String DOCACTIONBUTTON_SHOWACTIONNAME = "DOCACTIONBUTTON_SHOWACTIONNAME";
|
||||
public static final String DPVIEWS_SHOWINFOACCOUNT = "DPViews_ShowInfoAccount";
|
||||
public static final String DPVIEWS_SHOWINFOSCHEDULE = "DPViews_ShowInfoSchedule";
|
||||
public static final String EMAIL_NOTIFY_2PACK = "EMAIL_NOTIFY_2PACK";
|
||||
public static final String ENABLE_PAYMENTBOX_BUTTON = "ENABLE_PAYMENTBOX_BUTTON";
|
||||
public static final String GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS = "GRIDTABLE_LOAD_TIMEOUT_IN_SECONDS";
|
||||
public static final String HTML_REPORT_THEME = "HTML_REPORT_THEME";
|
||||
|
|
|
@ -48,6 +48,7 @@ import javax.mail.internet.MimeMultipart;
|
|||
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MSysConfig;
|
||||
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
|
||||
/**
|
||||
|
@ -72,7 +73,7 @@ public final class EMail implements Serializable
|
|||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -5857825644737211294L;
|
||||
private static final long serialVersionUID = 8117458371229316972L;
|
||||
|
||||
//use in server bean
|
||||
public final static String HTML_MAIL_MARKER = "ContentType=text/html;";
|
||||
|
@ -1200,4 +1201,12 @@ public final class EMail implements Serializable
|
|||
email.send();
|
||||
} // main
|
||||
|
||||
public void setHeader(String name, String value) {
|
||||
try {
|
||||
m_msg.setHeader(name, value);
|
||||
} catch (MessagingException e) {
|
||||
log.log(Level.WARNING, m_msg.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
} // EMail
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.compiere.model.MColumn;
|
|||
import org.compiere.model.MRole;
|
||||
import org.compiere.model.MTable;
|
||||
import org.compiere.model.PO;
|
||||
import org.compiere.model.X_AD_Package_Imp_Detail;
|
||||
import org.compiere.util.DB;
|
||||
import org.compiere.util.Env;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -95,8 +96,13 @@ public class GenericPOElementHandler extends AbstractElementHandler {
|
|||
element.unresolved = notfounds.toString();
|
||||
return;
|
||||
}
|
||||
String action = po.is_new() ? "New" : "Update";
|
||||
po.saveEx();
|
||||
element.recordId = po.get_ID();
|
||||
|
||||
X_AD_Package_Imp_Detail impDetail = createImportDetail(ctx, element.qName, po.get_TableName(), po.get_Table_ID());
|
||||
logImportDetail(ctx, impDetail, 1, po.toString(), element.recordId, action);
|
||||
|
||||
if ( I_AD_Window.Table_Name.equals(tableName)
|
||||
|| I_AD_Process.Table_Name.equals(tableName)
|
||||
|| I_AD_Role.Table_Name.equals(tableName)
|
||||
|
|
|
@ -51,6 +51,7 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
|
|||
Savepoint savepoint = null;
|
||||
PreparedStatement pstmt = null;
|
||||
X_AD_Package_Imp_Detail impDetail = null;
|
||||
impDetail = createImportDetail(ctx, element.qName, "", 0);
|
||||
try {
|
||||
// NOTE Postgres needs to commit DDL statements
|
||||
// add a SQL command just with COMMIT if you want to simulate the Oracle behavior (commit on DDL)
|
||||
|
@ -86,6 +87,8 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
|
|||
stmt = null;
|
||||
}
|
||||
}
|
||||
logImportDetail (ctx, impDetail, 1, "SQLStatement",1,"Execute");
|
||||
ctx.packIn.getNotifier().addSuccessLine("-> " + sql);
|
||||
} catch (Exception e) {
|
||||
// rollback immediately on exception to avoid a wrong SQL stop the whole process
|
||||
if (savepoint != null)
|
||||
|
@ -101,6 +104,9 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
|
|||
}
|
||||
savepoint = null;
|
||||
}
|
||||
ctx.packIn.getNotifier().addFailureLine("SQL statement failed but ignored, error (" + e.getLocalizedMessage() + "): " + sql);
|
||||
logImportDetail (ctx, impDetail, 0, "SQLStatement",1,"Execute");
|
||||
ctx.packIn.getNotifier().addFailureLine("-> " + sql);
|
||||
log.log(Level.SEVERE,"SQLSatement", e);
|
||||
} finally {
|
||||
DB.close(pstmt);
|
||||
|
@ -118,9 +124,6 @@ public class SQLStatementElementHandler extends AbstractElementHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
impDetail = createImportDetail(ctx, element.qName, "",
|
||||
0);
|
||||
logImportDetail (ctx, impDetail, 1, "SQLStatement",1,"Execute");
|
||||
}
|
||||
|
||||
public void endElement(PIPOContext ctx, Element element) throws SAXException {
|
||||
|
|
|
@ -78,6 +78,8 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
|
||||
packIn.setPackageVersion(packageVersion);
|
||||
packIn.setUpdateDictionary(false);
|
||||
packIn.getNotifier().setFileName(packageFile.getName());
|
||||
packIn.getNotifier().setPluginName(context.getBundle().getSymbolicName() + " v" + packageVersion);
|
||||
|
||||
adPackageImp = new X_AD_Package_Imp_Proc(Env.getCtx(), 0, null);
|
||||
if (logger.isLoggable(Level.INFO)) logger.info("zipFilepath->" + packageFile);
|
||||
|
@ -104,6 +106,7 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
if (logger.isLoggable(Level.INFO)) logger.info("commit " + trxName);
|
||||
} catch (Exception e) {
|
||||
adPackageImp.setP_Msg(e.getLocalizedMessage());
|
||||
packIn.getNotifier().addStatusLine(e.getLocalizedMessage());
|
||||
logger.log(Level.SEVERE, "importXML:", e);
|
||||
throw e;
|
||||
} finally {
|
||||
|
@ -122,6 +125,7 @@ public class PipoDictionaryService implements IDictionaryService {
|
|||
attachment.save(); // ignoring exceptions
|
||||
}
|
||||
}
|
||||
packIn.getNotifier().notifyRecipient();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,6 +100,14 @@ public abstract class AbstractElementHandler implements ElementHandler {
|
|||
detail.setSuccess(result);
|
||||
detail.setRecord_ID(objectID);
|
||||
ctx.packIn.addImportDetail(detail);
|
||||
StringBuilder msg = new StringBuilder(action).append(" ");
|
||||
if (detail.getTableName() != null)
|
||||
msg.append(detail.getTableName());
|
||||
msg.append("=").append(objectName).append("[").append(objectID).append("]");
|
||||
if (success == 1)
|
||||
ctx.packIn.getNotifier().addSuccessLine(msg.toString());
|
||||
else
|
||||
ctx.packIn.getNotifier().addFailureLine(msg.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,6 +61,7 @@ public class PackIn {
|
|||
private Map<String,Integer> columnCache = new HashMap<String,Integer>();
|
||||
private String packageName = null;
|
||||
private String packageVersion = null;
|
||||
private PackInNotifier notifier = new PackInNotifier(this);
|
||||
private X_AD_Package_Imp_Proc packinProc;
|
||||
|
||||
private List<X_AD_Package_Imp_Detail> importDetails;
|
||||
|
@ -176,7 +177,9 @@ public class PackIn {
|
|||
log.info(msg);
|
||||
if (handler.getUnresolvedCount() > 0)
|
||||
handler.dumpUnresolvedElements();
|
||||
return "Processed="+handler.getElementsProcessed()+" Un-Resolved="+handler.getUnresolvedCount();
|
||||
msg = "Processed="+handler.getElementsProcessed()+" Un-Resolved="+handler.getUnresolvedCount();
|
||||
getNotifier().addStatusLine(msg);
|
||||
return msg;
|
||||
} catch (Exception e) {
|
||||
log.log(Level.SEVERE, "importXML:", e);
|
||||
throw new RuntimeException(e.getLocalizedMessage(), e);
|
||||
|
@ -288,6 +291,10 @@ public class PackIn {
|
|||
this.packageVersion = packageVersion;
|
||||
}
|
||||
|
||||
public PackInNotifier getNotifier() {
|
||||
return notifier;
|
||||
}
|
||||
|
||||
public X_AD_Package_Imp_Proc getAD_Package_Imp_Proc() {
|
||||
if (packinProc.getAD_Package_Imp_Proc_ID() == 0)
|
||||
packinProc.saveEx(); // we need the ID to set
|
||||
|
|
|
@ -306,14 +306,13 @@ public class PackInHandler extends DefaultHandler {
|
|||
|
||||
updateRoleAccess();
|
||||
|
||||
if (!packageStatus.equals("Completed with errors")) {
|
||||
if (getUnresolvedCount() > 0) {
|
||||
packageStatus = "Completed - unresolved";
|
||||
} else {
|
||||
packageStatus = "Completed successfully";
|
||||
packIn.setSuccess(true);
|
||||
}
|
||||
}
|
||||
packIn.getNotifier().addStatusLine(packageStatus);
|
||||
|
||||
//Update package history log with package status
|
||||
packageImp.setPK_Status(packageStatus);
|
||||
|
@ -334,12 +333,14 @@ public class PackInHandler extends DefaultHandler {
|
|||
processElement(e);
|
||||
} catch (RuntimeException re) {
|
||||
packageStatus = "Import Failed";
|
||||
packIn.getNotifier().addStatusLine(packageStatus);
|
||||
//Update package history log with package status
|
||||
packageImp.setPK_Status(packageStatus);
|
||||
packageImp.saveEx();
|
||||
throw re;
|
||||
} catch (SAXException se) {
|
||||
packageStatus = "Import Failed";
|
||||
packIn.getNotifier().addStatusLine(packageStatus);
|
||||
//Update package history log with package status
|
||||
packageImp.setPK_Status(packageStatus);
|
||||
packageImp.saveEx();
|
||||
|
@ -487,6 +488,7 @@ public class PackInHandler extends DefaultHandler {
|
|||
if (e.unresolved != null && e.unresolved.length() > 0)
|
||||
s.append(" unresolved ").append(e.unresolved);
|
||||
log.warning(s.toString());
|
||||
packIn.getNotifier().addFailureLine(s.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
/**********************************************************************
|
||||
* This file is part of iDempiere ERP Open Source *
|
||||
* http://www.idempiere.org *
|
||||
* *
|
||||
* Copyright (C) Trek Global *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* Developer: *
|
||||
* - Carlos Ruiz - globalqss *
|
||||
**********************************************************************/
|
||||
|
||||
package org.adempiere.pipo2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.compiere.model.MClient;
|
||||
import org.compiere.model.MSysConfig;
|
||||
import org.compiere.util.EMail;
|
||||
import org.compiere.util.Env;
|
||||
import org.compiere.util.KeyNamePair;
|
||||
|
||||
/**
|
||||
* PackIn Notifier
|
||||
*
|
||||
* @author Carlos Ruiz - globalqss - sponsored by Trek Global
|
||||
*/
|
||||
|
||||
public class PackInNotifier {
|
||||
|
||||
private String fileName;
|
||||
private String pluginName;
|
||||
private List<KeyNamePair> knpLines = new ArrayList<KeyNamePair>();
|
||||
private PackIn packIn;
|
||||
|
||||
public PackInNotifier(PackIn packIn) {
|
||||
this.packIn = packIn;
|
||||
}
|
||||
|
||||
private static final int LEVEL_STATUS = 0;
|
||||
private static final int LEVEL_FAILURE = 1;
|
||||
private static final int LEVEL_SUCCESS = 2;
|
||||
|
||||
public void addStatusLine(String msg) {
|
||||
addLine(LEVEL_STATUS, msg);
|
||||
}
|
||||
|
||||
public void addFailureLine(String msg) {
|
||||
addLine(LEVEL_FAILURE, msg);
|
||||
}
|
||||
|
||||
public void addSuccessLine(String msg) {
|
||||
addLine(LEVEL_SUCCESS, msg);
|
||||
}
|
||||
|
||||
public void addLine(int level, String msg) {
|
||||
knpLines.add(new KeyNamePair(level, msg));
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setFileName(String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public void setPluginName(String pluginName) {
|
||||
this.pluginName = pluginName;
|
||||
}
|
||||
|
||||
public void notifyRecipient() {
|
||||
// get list from current tenant
|
||||
String emailList = MSysConfig.getValue(MSysConfig.EMAIL_NOTIFY_2PACK, "", Env.getAD_Client_ID(Env.getCtx())).trim();
|
||||
String emailSys = MSysConfig.getValue(MSysConfig.EMAIL_NOTIFY_2PACK, "", 0).trim();
|
||||
if (emailSys.length() > 0 && !emailList.equals(emailSys))
|
||||
emailList += "," + emailSys;
|
||||
if (emailList.length() == 0)
|
||||
return;
|
||||
|
||||
// Compose Subject
|
||||
StringBuilder subject = new StringBuilder("*");
|
||||
String status;
|
||||
if (packIn.isSuccess()) {
|
||||
status = "Success";
|
||||
} else {
|
||||
status = "Failure";
|
||||
}
|
||||
subject.append(status).append("* Result for PackIn ").append(getFileName());
|
||||
if (getPluginName() != null) {
|
||||
subject.append(" from ").append(getPluginName());
|
||||
}
|
||||
|
||||
// Body
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append("===========================\n");
|
||||
message.append("Packin File: ").append(getFileName()).append("\n");
|
||||
if (getPluginName() != null)
|
||||
message.append("Plugin: ").append(getPluginName()).append("\n");
|
||||
MClient client = MClient.get(Env.getCtx());
|
||||
message.append("Executed on: ").append(client.getName()).append("\n");
|
||||
message.append("Status: ").append(status).append("\n");
|
||||
for (String line : getLines(LEVEL_STATUS)) {
|
||||
message.append(line).append("\n");
|
||||
}
|
||||
message.append("===========================\n");
|
||||
|
||||
// --> if failed:
|
||||
List<String> fLines = getLines(LEVEL_FAILURE);
|
||||
if (fLines.size() > 0) {
|
||||
message.append("Failed Objects:").append("\n");
|
||||
for (String line : fLines) {
|
||||
message.append(line).append("\n");
|
||||
}
|
||||
message.append("===========================\n");
|
||||
}
|
||||
|
||||
List<String> sLines = getLines(LEVEL_SUCCESS);
|
||||
if (sLines.size() > 0) {
|
||||
message.append("Successful Objects:").append("\n");
|
||||
for (String line : sLines) {
|
||||
message.append(line).append("\n");
|
||||
}
|
||||
message.append("===========================\n");
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(emailList, " ,;", false);
|
||||
String to = st.nextToken();
|
||||
EMail email = client.createEMail(null, to, subject.toString(), message.toString());
|
||||
if (email != null)
|
||||
{
|
||||
if (!packIn.isSuccess())
|
||||
email.setHeader("X-Priority", "1");
|
||||
while (st.hasMoreTokens())
|
||||
email.addTo(st.nextToken());
|
||||
status = email.send();
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getLines(int levelStatus) {
|
||||
List<String> lines = new ArrayList<String>();
|
||||
for (KeyNamePair knp : knpLines) {
|
||||
if (knp.getKey() == levelStatus) {
|
||||
lines.add(knp.getName());
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
|
@ -75,8 +75,7 @@ public class PackInProcess extends SvrProcess {
|
|||
*/
|
||||
protected String doIt() throws Exception {
|
||||
|
||||
X_AD_Package_Imp_Proc adPackageImp = new X_AD_Package_Imp_Proc(getCtx(),
|
||||
p_PackIn_ID, get_TrxName());
|
||||
X_AD_Package_Imp_Proc adPackageImp = new X_AD_Package_Imp_Proc(getCtx(), p_PackIn_ID, null); // out of trx
|
||||
|
||||
// Create Target directory if required
|
||||
String packageDirectory = adPackageImp.getAD_Package_Dir();
|
||||
|
@ -134,14 +133,25 @@ public class PackInProcess extends SvrProcess {
|
|||
packIn.setPackageName(packageName);
|
||||
packIn.setPackageVersion(packageVersion);
|
||||
packIn.setUpdateDictionary(m_UpdateDictionary);
|
||||
packIn.getNotifier().setFileName(zipFilepath.getName());
|
||||
packIn.setAD_Package_Imp_Proc(adPackageImp);
|
||||
|
||||
// call XML Handler
|
||||
String msg = packIn.importXML(dict_file, getCtx(), get_TrxName());
|
||||
String msg;
|
||||
try {
|
||||
msg = packIn.importXML(dict_file, getCtx(), get_TrxName());
|
||||
adPackageImp.setDateProcessed(new Timestamp(System.currentTimeMillis()));
|
||||
adPackageImp.setP_Msg(msg);
|
||||
adPackageImp.saveEx();
|
||||
|
||||
} catch (Exception e) {
|
||||
adPackageImp.setP_Msg(e.getLocalizedMessage());
|
||||
packIn.getNotifier().addStatusLine(e.getLocalizedMessage());
|
||||
log.log(Level.SEVERE, "importXML:", e);
|
||||
throw e;
|
||||
} finally {
|
||||
adPackageImp.save(); // ignoring exceptions
|
||||
packIn.getNotifier().notifyRecipient();
|
||||
}
|
||||
return msg;
|
||||
} // doIt
|
||||
} // PackInProcess
|
||||
|
|
Loading…
Reference in New Issue