From db4f7155378276e5ab51bf0bda12af94faa06af5 Mon Sep 17 00:00:00 2001 From: hengsin Date: Tue, 5 Sep 2023 16:02:28 +0800 Subject: [PATCH] IDEMPIERE-5841 AD_Note created by Request causing Cross Tenant (#1991) --- .../base/event/AbstractEventHandler.java | 12 +++++ .../adempiere/base/event/EventManager.java | 47 ++++++++++++++++++- .../adempiere/base/event/IEventManager.java | 1 + .../base/event/RequestEventHandler.java | 2 +- .../src/org/compiere/model/MPInstance.java | 2 +- .../src/org/compiere/model/MRecentItem.java | 2 +- .../src/org/compiere/model/PO.java | 4 +- .../idempiere/broadcast/BroadcastMsgUtil.java | 2 +- .../adempiere/webui/dashboard/DPCalendar.java | 4 +- 9 files changed, 66 insertions(+), 10 deletions(-) diff --git a/org.adempiere.base/src/org/adempiere/base/event/AbstractEventHandler.java b/org.adempiere.base/src/org/adempiere/base/event/AbstractEventHandler.java index 9d049627d0..b37985ccec 100644 --- a/org.adempiere.base/src/org/adempiere/base/event/AbstractEventHandler.java +++ b/org.adempiere.base/src/org/adempiere/base/event/AbstractEventHandler.java @@ -13,8 +13,10 @@ *****************************************************************************/ package org.adempiere.base.event; +import java.util.Properties; import java.util.UUID; +import org.adempiere.util.ServerContext; import org.compiere.model.PO; import org.compiere.process.ProcessInfo; import org.osgi.service.event.Event; @@ -33,7 +35,13 @@ public abstract class AbstractEventHandler implements EventHandler { */ @Override public void handleEvent(Event event) { + Properties context = null; try { + if (event.containsProperty(IEventManager.EVENT_CONTEXT)) { + Properties eventContext = (Properties) event.getProperty(IEventManager.EVENT_CONTEXT); + context = ServerContext.getCurrentInstance(); + ServerContext.setCurrentInstance(eventContext); + } doHandleEvent(event); } catch (RuntimeException e) { addError(event, e); @@ -47,6 +55,10 @@ public abstract class AbstractEventHandler implements EventHandler { } catch (Throwable e) { addError(event, e); throw new Error(e); + } finally { + if (context != null) { + ServerContext.setCurrentInstance(context); + } } } diff --git a/org.adempiere.base/src/org/adempiere/base/event/EventManager.java b/org.adempiere.base/src/org/adempiere/base/event/EventManager.java index f08dc407e1..44993145fe 100644 --- a/org.adempiere.base/src/org/adempiere/base/event/EventManager.java +++ b/org.adempiere.base/src/org/adempiere/base/event/EventManager.java @@ -20,9 +20,11 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Properties; import org.adempiere.base.BaseActivator; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.event.Event; @@ -88,6 +90,16 @@ public class EventManager implements IEventManager { @Override public boolean postEvent(Event event) { if (eventAdmin != null) { + //copy current session context for restoration in asynchronous event thread + if (!event.containsProperty(EVENT_CONTEXT)) { + Map properties = new HashMap<>(); + for (String key : event.getPropertyNames()) { + properties.put(key, event.getProperty(key)); + } + properties.put(EVENT_CONTEXT, getCurrentSessionContext()); + event = newEvent(event.getTopic(), properties, true); + } + eventAdmin.postEvent(event); return true; } @@ -176,20 +188,35 @@ public class EventManager implements IEventManager { /** * @param topic * @param data - * @return + * @return new Event instance + */ + public static Event newEvent(String topic, Object data) { + return newEvent(topic, data, false); + } + + /** + * Create new event instance. If copySessionContext is true, a copy of current session context is added as EVENT_CONTEXT property to event data. + * @param topic + * @param data + * @param copySessionContext true to copy current session context (usually for postEvent). + * @return new Event instance */ @SuppressWarnings("unchecked") - public static Event newEvent(String topic, Object data) { + public static Event newEvent(String topic, Object data, boolean copySessionContext) { Event event = null; if (data instanceof Dictionary) { Dictionarydict = (Dictionary)data; if (dict.get(EVENT_ERROR_MESSAGES) == null) dict.put(EVENT_ERROR_MESSAGES, new ArrayList()); + if (copySessionContext) + dict.put(EVENT_CONTEXT, getCurrentSessionContext()); event = new Event(topic, dict); } else if (data instanceof Map) { Map map = (Map)data; if (!map.containsKey(EVENT_ERROR_MESSAGES)) map.put(EVENT_ERROR_MESSAGES, new ArrayList()); + if (copySessionContext) + map.put(EVENT_CONTEXT, getCurrentSessionContext()); event = new Event(topic, map); } else { Map map = new HashMap(3); @@ -197,11 +224,27 @@ public class EventManager implements IEventManager { if (data != null) map.put(EVENT_DATA, data); map.put(EVENT_ERROR_MESSAGES, new ArrayList()); + if (copySessionContext) + map.put(EVENT_CONTEXT, getCurrentSessionContext()); event = new Event(topic, map); } return event; } + /** + * @return copy of current session context + */ + private static Properties getCurrentSessionContext() { + Properties context = new Properties(); + Env.setContext(context, Env.AD_CLIENT_ID, Env.getAD_Client_ID(Env.getCtx())); + Env.setContext(context, Env.AD_ORG_ID, Env.getAD_Org_ID(Env.getCtx())); + Env.setContext(context, Env.AD_USER_ID, Env.getAD_User_ID(Env.getCtx())); + Env.setContext(context, Env.AD_ROLE_ID, Env.getAD_Role_ID(Env.getCtx())); + Env.setContext(context, Env.M_WAREHOUSE_ID, Env.getContext(Env.getCtx(), Env.M_WAREHOUSE_ID)); + Env.setContext(context, Env.LANGUAGE, Env.getContext(Env.getCtx(), Env.LANGUAGE)); + return context; + } + /** * * @param topic diff --git a/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java b/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java index 99b29fec86..1b5093f301 100644 --- a/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java +++ b/org.adempiere.base/src/org/adempiere/base/event/IEventManager.java @@ -24,6 +24,7 @@ import org.osgi.service.event.EventHandler; */ public interface IEventManager { + public static final String EVENT_CONTEXT = "event.context"; public static final String EVENT_DATA = "event.data"; public static final String EVENT_ERROR_MESSAGES = "event.errorMessages"; public static final String IMPORT_TABLE_NAME_PROPERTY = "importTableName"; diff --git a/org.adempiere.base/src/org/adempiere/base/event/RequestEventHandler.java b/org.adempiere.base/src/org/adempiere/base/event/RequestEventHandler.java index 6f2b0e5b42..6f5841175c 100644 --- a/org.adempiere.base/src/org/adempiere/base/event/RequestEventHandler.java +++ b/org.adempiere.base/src/org/adempiere/base/event/RequestEventHandler.java @@ -369,7 +369,7 @@ public class RequestEventHandler extends AbstractEventHandler implements Managed || X_AD_User.NOTIFICATIONTYPE_EMailPlusNotice.equals(NotificationType)) { RequestSendEMailEventData eventData = new RequestSendEMailEventData(client, from, to, subject, message.toString(), pdf, r.getR_Request_ID()); - Event event = EventManager.newEvent(IEventTopics.REQUEST_SEND_EMAIL, eventData); + Event event = EventManager.newEvent(IEventTopics.REQUEST_SEND_EMAIL, eventData, true); EventManager.getInstance().postEvent(event); } // Send Note diff --git a/org.adempiere.base/src/org/compiere/model/MPInstance.java b/org.adempiere.base/src/org/compiere/model/MPInstance.java index cfc89fec96..98702ffb93 100644 --- a/org.adempiere.base/src/org/compiere/model/MPInstance.java +++ b/org.adempiere.base/src/org/compiere/model/MPInstance.java @@ -470,7 +470,7 @@ public class MPInstance extends X_AD_PInstance public static void postOnChangedEvent(int AD_User_ID) { Map properties = new HashMap(); properties.put("AD_User_ID", AD_User_ID); - Event event = new Event(ON_RUNNING_JOB_CHANGED_TOPIC, properties); + Event event = EventManager.newEvent(ON_RUNNING_JOB_CHANGED_TOPIC, properties, true); EventManager.getInstance().postEvent(event); } diff --git a/org.adempiere.base/src/org/compiere/model/MRecentItem.java b/org.adempiere.base/src/org/compiere/model/MRecentItem.java index 6825d41d10..54bdc5298e 100644 --- a/org.adempiere.base/src/org/compiere/model/MRecentItem.java +++ b/org.adempiere.base/src/org/compiere/model/MRecentItem.java @@ -275,7 +275,7 @@ public class MRecentItem extends X_AD_RecentItem implements ImmutablePOSupport public static void postOnChangedEvent(int AD_User_ID) { Map properties = new HashMap(); properties.put("AD_User_ID", AD_User_ID); - Event event = new Event(ON_RECENT_ITEM_CHANGED_TOPIC, properties); + Event event = EventManager.newEvent(ON_RECENT_ITEM_CHANGED_TOPIC, properties, true); EventManager.getInstance().postEvent(event); } diff --git a/org.adempiere.base/src/org/compiere/model/PO.java b/org.adempiere.base/src/org/compiere/model/PO.java index 0e8dcdfe28..4b575bebd3 100644 --- a/org.adempiere.base/src/org/compiere/model/PO.java +++ b/org.adempiere.base/src/org/compiere/model/PO.java @@ -2655,7 +2655,7 @@ public abstract class PO { //post osgi event String topic = newRecord ? IEventTopics.PO_POST_CREATE : IEventTopics.PO_POST_UPADTE; - Event event = EventManager.newEvent(topic, this); + Event event = EventManager.newEvent(topic, this, true); EventManager.getInstance().postEvent(event); if (s_docWFMgr == null) @@ -4233,7 +4233,7 @@ public abstract class PO } //osgi event handler - Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this); + Event event = EventManager.newEvent(IEventTopics.PO_POST_DELETE, this, true); EventManager.getInstance().postEvent(event); m_idOld = 0; diff --git a/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java b/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java index 61d6e79fd8..7e67131c3b 100644 --- a/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java +++ b/org.adempiere.base/src/org/idempiere/broadcast/BroadcastMsgUtil.java @@ -128,7 +128,7 @@ public class BroadcastMsgUtil public void run() { org.osgi.service.event.Event event = EventManager.newEvent( - IEventTopics.BROADCAST_MESSAGE, msg); + IEventTopics.BROADCAST_MESSAGE, msg, true); EventManager.getInstance().postEvent(event); } }; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java index 2d2dfb1c24..633e61d315 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/DPCalendar.java @@ -581,7 +581,7 @@ public class DPCalendar extends DashboardPanel implements EventListener, @Override public void onMessage(Map message) { - org.osgi.service.event.Event requestChangedEvent = new org.osgi.service.event.Event(ON_REQUEST_CHANGED_TOPIC, message); + org.osgi.service.event.Event requestChangedEvent = EventManager.newEvent(ON_REQUEST_CHANGED_TOPIC, message, true); EventManager.getInstance().postEvent(requestChangedEvent); } @@ -635,7 +635,7 @@ public class DPCalendar extends DashboardPanel implements EventListener, ITopic> topic = service.getTopic(ON_REQUEST_CHANGED_TOPIC); topic.publish(message); } else { - org.osgi.service.event.Event requestChangedEvent = new org.osgi.service.event.Event(ON_REQUEST_CHANGED_TOPIC, message); + org.osgi.service.event.Event requestChangedEvent = EventManager.newEvent(ON_REQUEST_CHANGED_TOPIC, message, true); EventManager.getInstance().postEvent(requestChangedEvent); } }